package com.lonely.inventory.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lonely.common.core.domain.BaseEntity;
import com.lonely.common.core.page.Condition;
import com.lonely.common.utils.JsonUtil;
import com.lonely.common.utils.SecurityUtils;
import com.lonely.inventory.domain.dto.stockup.flowwater.StockUpInventoryFlowWaterComparisonDataDTO;
import com.lonely.inventory.domain.dto.stockup.flowwater.StockUpInventoryFlowWaterPageQueryDto;
import com.lonely.inventory.domain.entity.SysInventoryStorageArchive;
import com.lonely.inventory.domain.entity.SysStockUpInventory;
import com.lonely.inventory.domain.entity.SysStockUpInventoryFlowWater;
import com.lonely.inventory.domain.entity.SysStockUpInventorySizeInfo;
import com.lonely.inventory.domain.vo.stockup.flowwater.StockUpInventoryFlowWaterPageQueryVo;
import com.lonely.inventory.enums.StockUpInventoryEnum;
import com.lonely.inventory.mapper.SysStockUpInventoryFlowWaterMapper;
import com.lonely.inventory.service.IStockUpInventoryFlowWaterService;
import com.lonely.inventory.service.IStorageArchiveService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author : 黄志标
 * @date: 2025/9/26 13:24
 * @description: 备货库存流水服务实现类
 */
@Service
public class StockUpInventoryFlowWaterServiceImpl extends ServiceImpl<SysStockUpInventoryFlowWaterMapper, SysStockUpInventoryFlowWater> implements IStockUpInventoryFlowWaterService {

    @Autowired
    private IStorageArchiveService storageArchiveService;

    /**
     * 分页查询
     *
     * @param queryDto
     * @return
     */
    @Override
    public Page<StockUpInventoryFlowWaterPageQueryVo> page(StockUpInventoryFlowWaterPageQueryDto queryDto) {
        Page<StockUpInventoryFlowWaterPageQueryVo> page = Condition.page(queryDto);
        page = super.getBaseMapper().page(page, queryDto);

        if (CollUtil.isNotEmpty(page.getRecords())) {
            page.setRecords(page.getRecords().stream().peek(x -> {
                List<StockUpInventoryFlowWaterComparisonDataDTO> beforeData = new ArrayList<>();
                if (StrUtil.isNotBlank(x.getBeforeDataStr())) {
                    beforeData = JsonUtil.parseArray(x.getBeforeDataStr(), StockUpInventoryFlowWaterComparisonDataDTO.class);
                    beforeData = fillStorageName(beforeData);
                }

                List<StockUpInventoryFlowWaterComparisonDataDTO> afterData = new ArrayList<>();
                if (StrUtil.isNotBlank(x.getAfterDataStr())) {
                    afterData = JsonUtil.parseArray(x.getAfterDataStr(), StockUpInventoryFlowWaterComparisonDataDTO.class);
                    afterData = fillStorageName(afterData);
                }

                x.setBeforeData(beforeData);
                x.setAfterData(afterData);
            }).collect(Collectors.toList()));
        }
        return page;
    }


    /**
     * 添加流水
     *
     * @param stockUpInventory
     * @param oldStockUpInventorySizeInfos
     * @param newStockUpInventorySizeInfos
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addFlowWater(SysStockUpInventory stockUpInventory, StockUpInventoryEnum.StockUpInventoryOperationType operationType,
                             List<SysStockUpInventorySizeInfo> oldStockUpInventorySizeInfos, List<SysStockUpInventorySizeInfo> newStockUpInventorySizeInfos) {
        Assert.notEmpty(newStockUpInventorySizeInfos, "没有更新后的尺码信息...");

        SysStockUpInventoryFlowWater inventoryFlowWater = new SysStockUpInventoryFlowWater();
        inventoryFlowWater.setStockUpInventoryId(stockUpInventory.getId());
        inventoryFlowWater.setOperationType(operationType.getType());

        // 处理操作前数据
        List<StockUpInventoryFlowWaterComparisonDataDTO> beforeData;
        if (CollUtil.isEmpty(oldStockUpInventorySizeInfos)) {
            beforeData = newStockUpInventorySizeInfos.stream().map(x -> {
                StockUpInventoryFlowWaterComparisonDataDTO comparisonDataDTO = new StockUpInventoryFlowWaterComparisonDataDTO();
                comparisonDataDTO.setColor(x.getColor());
                comparisonDataDTO.setStorageArchiveId(null);
                comparisonDataDTO.setSizeName(x.getSizeName());
                comparisonDataDTO.setStockQuantity(0);
                return comparisonDataDTO;
            }).collect(Collectors.toList());
        } else {
            Map<Long, SysStockUpInventorySizeInfo> oldSizeInfoMap = oldStockUpInventorySizeInfos.stream().collect(Collectors.toMap(BaseEntity::getId, x -> x, (x, y) -> x));
            beforeData = newStockUpInventorySizeInfos.stream().map(x -> {
                // 判断是否存在操作前的数据中
                if(oldSizeInfoMap.containsKey(x.getId())){
                    SysStockUpInventorySizeInfo sizeInfo = oldSizeInfoMap.get(x.getId());
                    StockUpInventoryFlowWaterComparisonDataDTO comparisonDataDTO = new StockUpInventoryFlowWaterComparisonDataDTO();
                    comparisonDataDTO.setColor(sizeInfo.getColor());
                    comparisonDataDTO.setStorageArchiveId(sizeInfo.getStorageArchiveId());
                    comparisonDataDTO.setSizeName(sizeInfo.getSizeName());
                    comparisonDataDTO.setStockQuantity(sizeInfo.getStockQuantity());
                    return comparisonDataDTO;
                }

                // 新增的数据
                StockUpInventoryFlowWaterComparisonDataDTO comparisonDataDTO = new StockUpInventoryFlowWaterComparisonDataDTO();
                comparisonDataDTO.setColor(x.getColor());
                comparisonDataDTO.setStorageArchiveId(x.getStorageArchiveId());
                comparisonDataDTO.setSizeName(x.getSizeName());
                comparisonDataDTO.setStockQuantity(0);
                return comparisonDataDTO;
            }).collect(Collectors.toList());
        }
        inventoryFlowWater.setBeforeData(JsonUtil.toJsonString(beforeData));

        // 处理操作后数据
        List<StockUpInventoryFlowWaterComparisonDataDTO> afterData = newStockUpInventorySizeInfos.stream().map(x -> {
            StockUpInventoryFlowWaterComparisonDataDTO comparisonDataDTO = new StockUpInventoryFlowWaterComparisonDataDTO();
            comparisonDataDTO.setColor(x.getColor());
            comparisonDataDTO.setStorageArchiveId(x.getStorageArchiveId());
            comparisonDataDTO.setSizeName(x.getSizeName());
            comparisonDataDTO.setStockQuantity(ObjectUtil.defaultIfNull(x.getStockQuantity(), 0));
            return comparisonDataDTO;
        }).collect(Collectors.toList());
        inventoryFlowWater.setAfterData(JsonUtil.toJsonString(afterData));
        inventoryFlowWater.setCreateBy(SecurityUtils.getUserId());
        inventoryFlowWater.setUpdateBy(SecurityUtils.getUserId());

        super.save(inventoryFlowWater);

    }

    /**
     * 填充库位码信息
     *
     * @param flowWaterDatas
     * @return
     */
    private List<StockUpInventoryFlowWaterComparisonDataDTO> fillStorageName(List<StockUpInventoryFlowWaterComparisonDataDTO> flowWaterDatas) {
        if (CollUtil.isNotEmpty(flowWaterDatas)) {
            List<Long> archiveId = flowWaterDatas.stream().map(StockUpInventoryFlowWaterComparisonDataDTO::getStorageArchiveId).filter(Objects::nonNull).distinct().collect(Collectors.toList());
            if (CollUtil.isNotEmpty(archiveId)) {
                Map<Long, String> archiveNameMap = this.storageArchiveService.listByIds(archiveId).stream().collect(Collectors.toMap(BaseEntity::getId, SysInventoryStorageArchive::getStorageName, (v1, v2) -> v1));
                flowWaterDatas = flowWaterDatas.stream().peek(currentData -> {
                    if (currentData.getStorageArchiveId() != null && archiveNameMap.containsKey(currentData.getStorageArchiveId())) {
                        currentData.setStorageName(archiveNameMap.get(currentData.getStorageArchiveId()));
                    }
                }).collect(Collectors.toList());

            }
        }
        return flowWaterDatas;
    }
}
